using System;
using System.Diagnostics;
using System.Management;

namespace Pixeldyne.Core.SystemResources
{
	/// <summary>
	/// Retrieves system information, e.g. uptime, CPU usage, avail. RAM, etc.
	/// </summary>
	public class SystemInfo : IDisposable
	{
		private PerformanceCounter cpuCounter;
		private PerformanceCounter ramCounter;

		public long GetDiskSize(string drive)
		{
			var disk = new ManagementObject("win32_logicaldisk.deviceid=\"" + drive + ":\"");
			disk.Get();

			return Convert.ToInt64(disk["Size"]);
		}

		public long GetDiskFreeSpace(string drive)
		{
			var disk = new ManagementObject("win32_logicaldisk.deviceid=\"" + drive + ":\"");
			disk.Get();

			return Convert.ToInt64(disk["FreeSpace"]);
		}

		/// <summary>
		/// Get current CPU usage (as percentage).
		/// </summary>
		/// <returns></returns>
		public string CurrentCpuUsage
		{
			get
			{
				return cpuCounter.NextValue() + "%";
			}
		}


		/// <summary>
		/// Get available RAM in MBytes.
		/// </summary>
		public string AvailableRAM
		{
			get
			{
				return ramCounter.NextValue() + "MB";
			}
		}


		/// <summary>
		/// Retrieves current system uptime.
		/// </summary>
		/// <returns></returns>
		public static TimeSpan Uptime
		{
			get
			{
				var pc = new PerformanceCounter ("System", "System Up Time", true);
				pc.NextValue(); 
				return TimeSpan.FromSeconds(pc.NextValue());
			}
		}


		/// <summary>
		/// Initialises system information including required system performance counters
		/// </summary>
		public SystemInfo()
		{
			cpuCounter = new PerformanceCounter
			             	{
			             		CategoryName = "Processor",
			             		CounterName = "% Processor Time",
			             		InstanceName = "_Total"
			             	};

			ramCounter = new PerformanceCounter("Memory", "Available MBytes");
		}


		#region IDisposable Members

		/// <summary>
		/// Dispose of this object
		/// </summary>
		public void Dispose()
		{
			ramCounter.Dispose();
			cpuCounter.Dispose();

			GC.SuppressFinalize(this);
		}

		#endregion
	}
}
